package com.hwtx.soa.registry;

import com.alibaba.fastjson.JSON;
import com.hzgj.bcl.soa.registry.Provider;
import com.hzgj.bcl.soa.registry.RegistryUpdater;
import com.hzgj.bcl.util.reg.EtcdExtClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.hwtx.soa.registry.EtcdConstants.*;
import static com.hzgj.bcl.soa.registry.RegistryConstants.SERVICE_PREFIX;

/**
 * Created by warning5 on 17-2-17.
 */
public class EtcdRegistryUpdater implements RegistryUpdater {

    protected static final Logger logger = LoggerFactory.getLogger(EtcdRegistry.class);
    protected EtcdExtClient client;
    protected int ttl;

    public EtcdRegistryUpdater(EtcdExtClient client, int ttl) {
        this.client = client;
        this.ttl = ttl;
    }

    @Override
    public Result downService(String service, String ipAndPort) throws Exception {
        String rawKey = getUpDir(service, ipAndPort);
        Provider provider = getProvider(rawKey);
        Result result;
        if (provider == null) {
            return new Result(false, "service " + service + " not exist,can't down it.");
        }
        String dir = getDownServicePath(service);
        if (putProvider(dir + "/" + ipAndPort, provider)) {
            if (client.deleteDir(rawKey)) {
                result = getResult(true, "down service " + service + " of " + ipAndPort + " success.");
            } else {
                client.deleteDir(dir + "/" + ipAndPort);
                result = getResult(false, "delete up service " + service + " of " + ipAndPort + " failure,up it again.");
            }
        } else {
            result = getResult(false, "down service " + service + " of " + ipAndPort + " failure. ");
        }
        return result;
    }

    @Override
    public Result upService(String service, String ipAndPort) throws Exception {
        String dir = getDownServicePath(service);
        Result result;
        Provider provider = getProvider(dir + ipAndPort);
        if (provider == null) {
            return new Result(false, "service " + service + " not exist,can't up it.");
        }
        if (putProvider(getUpDir(service, ipAndPort), provider)) {
            if (client.deleteDir(dir + ipAndPort)) {
                result = getResult(true, "up service " + service + " of " + ipAndPort + " success.");
            } else {
                client.deleteDir(getUpDir(service, ipAndPort));
                result = getResult(false, "delete down service " + service + " of " + ipAndPort + " failure, down it again.");
            }
        } else {
            result = getResult(false, "up service " + service + " of " + ipAndPort + " failure.");
        }

        return result;
    }

    private Result getResult(boolean success, String message) {
//        logger.info(message);
        return new Result(success, message);
    }

    private Provider getProvider(String dir) {
        return client.getValue(dir, Provider.class);
    }

    private boolean putProvider(String dir, Provider provider) throws Exception {
        return client.put(dir, JSON.toJSONString(provider), ttl);
    }

    private String getUpDir(String service, String ipAndPort) {
        return SERVICE_PREFIX + "/" + service + "/" + SERVICE_PROVIDERS + "/" + ipAndPort;
    }

}
